package cn.jishiyu11.xeqb.utils

import android.content.Context
import android.content.SharedPreferences.Editor

import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject

import java.lang.reflect.InvocationTargetException
import java.lang.reflect.Method
import java.util.ArrayList
import java.util.HashMap

import cn.jishiyu11.xeqb.R

/**
 * @author A18ccms A18ccms_gmail_com
 * @version V1.0
 * @Title: SharedPreferencesUtils.java
 * @Description: TODO 保存基本信息
 * @date 2016-3-8 下午4:16:29
 */
object SharedPreferencesUtils {

    /**
     * 保存在手机里面的文件名
     */
    val FILE_NAME = "share_data"

    /**
     * 保存数据的方法，我们需要拿到保存数据的具体类型，然后根据类型调用不同的保存方法
     *
     * @param context
     * @param key
     * @param `values`
     */
    fun put(context: Context?, key: String?, values: Any?) {
        if (values == null || context == null || key == null)
            return
        val sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE)
        val editor = sp.edit()

        if (values is String) {
            editor.putString(key, values as String?)
        } else if (values is Int) {
            editor.putInt(key, (values as Int?)!!)
        } else if (values is Boolean) {
            editor.putBoolean(key, (values as Boolean?)!!)
        } else if (values is Float) {
            editor.putFloat(key, (values as Float?)!!)
        } else if (values is Long) {
            editor.putLong(key, (values as Long?)!!)
        } else {
            editor.putString(key, values.toString())
        }

        SharedPreferencesCompat.apply(editor)
    }

    /**
     * 得到保存数据的方法，我们根据默认值得到保存的数据的具体类型，然后调用相对于的方法获取值
     * @param context
     * @param key
     * @param defaultObject
     * @return
     */
    operator fun get(context: Context?, key: String?, defaultObject: Any?): Any {
        if (defaultObject == null || context == null || key == null)
            return ""
        val sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE)

        if (defaultObject is String) {
            return if (sp.getString(key, defaultObject as String?) != "") {
                sp.getString(key, defaultObject as String?)
            } else
                ""
        } else if (defaultObject is Int) {
            return if ("" != sp.getInt(key, (defaultObject as Int?)!!).toString() + "") {
                sp.getInt(key, (defaultObject as Int?)!!)
            } else
                0
        } else if (defaultObject is Boolean) {
            return if ("" != sp.getBoolean(key, (defaultObject as Boolean?)!!).toString() + "") {
                sp.getBoolean(key, (defaultObject as Boolean?)!!)
            } else
                false
        } else if (defaultObject is Float) {
            return if ("" != sp.getFloat(key, (defaultObject as Float?)!!).toString() + "") {
                sp.getFloat(key, (defaultObject as Float?)!!)
            } else
                0
        } else if (defaultObject is Long) {
            return if ("" != sp.getLong(key, (defaultObject as Long?)!!).toString() + "") {
                sp.getLong(key, (defaultObject as Long?)!!)
            } else
                0
        }
        return ""
    }

    fun saveInfo(context: Context, datas: List<Map<String, Any>>): String {
        val mJsonArray = JSONArray()
        for (i in datas.indices) {
            val itemMap = datas[i]
            val iterator = itemMap.entries.iterator()
            val map = JSONObject()
            while (iterator.hasNext()) {
                val entry = iterator.next()
                try {
                    map.put(entry.key, entry.value)
                } catch (ignored: JSONException) {

                }

            }
            mJsonArray.put(map)
        }
        return mJsonArray.toString()
    }

    fun getInfo(context: Context, result: String): MutableList<Map<String, Any>> {
        val datas = ArrayList<Map<String, Any>>()
        try {
            val array = JSONArray(result)
            for (i in 0 until array.length()) {
                val itemObject = array.getJSONObject(i)
                val itemMap = HashMap<String, Any>()
                val names = itemObject.names()
                if (names != null) {
                    for (j in 0 until names.length()) {
                        val name = names.getString(j)
                        val value = itemObject.getString(name)
                        itemMap[name] = value
                    }
                }
                datas.add(itemMap)
            }
        } catch (ignored: JSONException) {

        }

        return datas
    }

    /**
     * 移除某个key值已经对应的值
     * @param context
     * @param key
     */
    fun remove(context: Context, key: String) {
        val sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE)
        val editor = sp.edit()
        editor.remove(key)
        SharedPreferencesCompat.apply(editor)
    }

    /**
     * 清除所有数据
     * @param context
     */
    fun clear(context: Context) {
        val sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE)
        val editor = sp.edit()
        editor.clear()
        SharedPreferencesCompat.apply(editor)
    }

    /**
     * 查询某个key是否已经存在
     * @param context
     * @param key
     * @return
     */
    fun contains(context: Context, key: String): Boolean {
        val sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE)
        return sp.contains(key)
    }

    /**
     * 返回所有的键值对
     * @param context
     * @return
     */
    fun getAll(context: Context): Map<String, *> {
        val sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE)
        return sp.all
    }

    /**
     * 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类
     * @author zhy
     */
    private object SharedPreferencesCompat {
        private val sApplyMethod = findApplyMethod()

        /**
         * 反射查找apply的方法
         * @return
         */
        private fun findApplyMethod(): Method? {
            try {
                val clz = Editor::class.java
                return clz.getMethod("apply")
            } catch (ignored: NoSuchMethodException) {
            }

            return null
        }

        /**
         * 如果找到则使用apply执行，否则使用commit
         * @param editor
         */
        fun apply(editor: Editor) {
            try {
                if (sApplyMethod != null) {
                    sApplyMethod.invoke(editor)
                    return
                }
            } catch (ignored: IllegalArgumentException) {
            } catch (ignored: IllegalAccessException) {
            } catch (ignored: InvocationTargetException) {
            }

            editor.commit()
        }
    }

    fun shareremvo(context: Context, key: String) {
        val mShared = context.getSharedPreferences(FILE_NAME, 0)
        val editor = mShared.edit()
        editor.remove(key)
        editor.commit()
    }


    /**
     * 登出 @Title: loginSuccess @author: xusonghui @Description:
     * myLoginData @return: void @throws
     */
    fun logoutSuccess(content: Context) {
        SharedPreferencesUtils.shareremvo(content, content.getString(R.string.username))
        SharedPreferencesUtils.shareremvo(content, content.getString(R.string.uid))
        SharedPreferencesUtils.shareremvo(content, content.getString(R.string.password))
        SharedPreferencesUtils.shareremvo(content, content.getString(R.string.phoneNo))
        SharedPreferencesUtils.shareremvo(content, content.getString(R.string.userNo))
    }
}
